using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Phoenix.Xna.Framework.Components.Cameras;
using Phoenix.Xna.Framework.Graphics.Animation;
using Phoenix.Xna.Framework.Graphics.Lights;

namespace Phoenix.Xna.Framework.Graphics.Models
{
    public class SkinnedModel : ModelBase
    {
        public Model Model { get; private set; }
        public SkinnedModelBoneCollection SkeletonBones { get; private set; }
        public AnimationClipDictionary AnimationClips { get; private set; }
        public AnimationController AnimationController { get; private set; }

        private SkinnedModel()
            : base()
        {
        }

        public void StartClip(string clip)
        {
            AnimationController.StartClip(AnimationClips[clip]);
        }

        public void CrossFade(string clip, TimeSpan fadeTime)
        {
            AnimationController.CrossFade(AnimationClips[clip], fadeTime);
        }

        #region IComponent Members

        public override void Initialize()
        {
            AnimationController = new AnimationController(SkeletonBones);
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            if (Enabled)
            {
                AnimationController.Update(gameTime.ElapsedGameTime, Matrix.Identity);
                base.Update(gameTime);
            }
        }

        #endregion

        #region IDrawableComponent Members

        public override void Draw(GameTime gameTime)
        {
            if (Visible)
            {
                Engine.Instance.GraphicsDevice.RenderState.DepthBufferEnable = true;
                Engine.Instance.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
                foreach (ModelMesh modelMesh in Model.Meshes)
                {
                    foreach (ModelMeshPart meshPart in modelMesh.MeshParts)
                    {
                        SkinnedModelBasicEffect basicEffect = (SkinnedModelBasicEffect)meshPart.Effect;

                        basicEffect.World = Matrix.CreateFromYawPitchRoll(EulerRotation.X, EulerRotation.Y, EulerRotation.Z) *
                            Matrix.CreateTranslation(Position);
                        basicEffect.Bones = AnimationController.SkinnedBoneTransforms;
                        basicEffect.View = Camera.ActiveCamera.View;
                        basicEffect.Projection = Camera.ActiveCamera.Projection; ;

                        // OPTIONAL - Configure material
                        basicEffect.Material.DiffuseColor = new Vector3(0.8f);
                        basicEffect.Material.SpecularColor = new Vector3(0.3f);
                        basicEffect.Material.SpecularPower = 8;

                        basicEffect.NormalMapEnabled = false;

                        basicEffect.SpecularMapEnabled = false;
                        basicEffect.SpecularMap = null;
                        //if (false)
                        //    basicEffect.Material.SpecularColor = new Vector3(1.0f);

                        // OPTIONAL - Configure lights
                        basicEffect.AmbientLightColor = new Vector3(3.1f);
                        basicEffect.LightEnabled = true;
                        basicEffect.EnabledLights = EnabledLights.One;
                        basicEffect.PointLights[0].Color = Vector3.One;
                        basicEffect.PointLights[0].Position = new Vector3(100, 100, 100);
                    }

                    modelMesh.Draw();
                }
            }
        }

        #endregion
    }
}